package com.lnyt.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lnyt.dao.t12306.TicketTaskMapper;
import com.lnyt.dao.t12306.TicketStore;
import com.lnyt.dao.t12306.TicketUserMapper;
import com.lnyt.dao.t12306.TrainStationMapper;
import com.lnyt.pojo.ticket.TicketTask;
import com.lnyt.pojo.ticket.TicketUser;
import com.lnyt.pojo.ticket.TrainNumber;
import com.lnyt.pojo.ticket.TrainStation;
import com.lnyt.service.TicketReqService;
import com.lnyt.util.CheckUtil;
import com.lnyt.util.LogUtil;
import com.lnyt.util.MessageUtil;
import com.lnyt.util.TicketUtil;
import com.lnyt.util.factroy.OkHttpClientFactroy;
import com.lnyt.util.factroy.TicketFactroy;
import okhttp3.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;


@Service
@Transactional
public class TicketReqServiceImpl implements TicketReqService {
    // 缓存
    @Resource
    private TicketStore ticketStore;
    // 订单Dao
    @Resource
    private TicketTaskMapper ticketTaskMapper;
    // 用户Dao
    @Resource
    private TicketUserMapper ticketUserMapper;
    // 车站Dao
    @Resource
    private TrainStationMapper trainStationMapper;

    // Url表
    private Map<String, String> urlMap;

    public Map<String, String> getUrlMap() {
        return urlMap;
    }
    public void setUrlMap(Map<String, String> urlMap) {
        this.urlMap = urlMap;
    }

    public TicketStore getTicketStore() {
        return ticketStore;
    }
    public void setTicketStore(TicketStore ticketStore) {
        this.ticketStore = ticketStore;
    }

    /*------------------------------------------------------------------------------------------*/
    /* 观察者响应
    /*------------------------------------------------------------------------------------------*/
    @Override
    public synchronized void update(Observable o, Object arg) {
        JSONObject reqData = (JSONObject)arg;
        String trainKey = reqData.getString("key");

        for (Map.Entry<String, TicketUser> item : ticketStore.getTicketUserMap().entrySet()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (item.getValue().getOkHttpClient() == null) {
                        return;
                    }

                    for (TicketTask ticketTask : item.getValue().getTicketTaskMap().values()) {
                        if (ticketTask.getTrainId().equals(trainKey)) {
                            String userId = ticketTask.getUserId();
                            String status = ticketTask.getStatus();
                            OkHttpClient okHttpClient = ticketStore.getUserOkHttpClient(userId);
                            TicketUser ticketUser = ticketStore.getTicketUserMap().get(userId);

                            try {
                                if (status != null && status.equals("Work")) {
                                    // 设置尝试下单状态与时间
                                    ticketTask.setStatus("Trying");
                                    ticketTask.setDate(LogUtil.formatDate(new Date(), "yyyy-MM-dd hh:mm:ss"));

                                    autoStep(reqData, ticketTask, okHttpClient);
                                }
                            } catch (Exception exc) {
                                exc.printStackTrace();
                            }
                        }
                    }
                }
            }).start();
        }
    }

    /*------------------------------------------------------------------------------------------*/
    /* 初始化
    /*------------------------------------------------------------------------------------------*/
    @Override
    public void initService() {
        ticketTaskMapper.init();
        ticketUserMapper.init();
        trainStationMapper.init();

        initStationsDataBase();
    }

    // 初始化车站数据库
    private void initStationsDataBase() {
        OkHttpClient okHttpClient = OkHttpClientFactroy.creator();
        Request request = new Request.Builder()
                .url(urlMap.get("stationInfo"))
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    Map<String, String> varMap = TicketUtil.getHtmlVarMap(resBody.string());
                    String[] stationStrs = varMap.get("station_names").split("@");

                    for (String stationStr : stationStrs) {
                        if (stationStr.length() == 0) {
                            continue;
                        }

                        TrainStation station = TicketFactroy.createTrainStation(stationStr);
                        TrainStation hasItem = trainStationMapper.select(station);

                        if (hasItem == null) {
                            trainStationMapper.insert(station);
                        }
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
        }

        LogUtil.log4j2().info("Get stations done!");
    }

    /*------------------------------------------------------------------------------------------*/
    /* 请求执行函数
    /*------------------------------------------------------------------------------------------*/
    @Override
    public String signInit(OkHttpClient okHttpClient) {
        String result = null;

        Request request = new Request.Builder()
                .url(urlMap.get("signInit"))
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("text/html")) {
                        result = resBody.string();
                        LogUtil.log4j2().info("Pass Init");
                    }

                    resBody.close();
                }
            }
        } catch (IOException exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("initSeasion");
        }

        return result;
    }

    @Override
    public String signUamtk(OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("appid", "otn").build();

        Request request = new Request.Builder()
                .url((String) (urlMap.get("signUamtk")))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"result_code\":400}";
                    }

                    resBody.close();
                }
            }
        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signUamtk");
        }

        return result;
    }

    @Override
    public String signCaptch(OkHttpClient okHttpClient) {
        String result = null;

        Request request = new Request.Builder()
                .url(urlMap.get("signCaptcha"))
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                // 返回Base64字符串
                ResponseBody resBody = response.body();

                if (resBody != null) {
                    result = Base64Utils.encodeToString(resBody.bytes());
                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signCaptcha");
        }

        return result;
    }

    @Override
    public String signCaptchCheck(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("answer", reqData.getString("pos"))
                .add("login_site", "E")
                .add("rand", "sjrand")
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("signCheck"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"result_code\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signCaptchaCheck");
        }

        return result;
    }

    @Override
    public String signLogin(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("username", reqData.getString("username"))
                .add("password", reqData.getString("password"))
                .add("appid", "otn")
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("signLogin"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"result_code\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signLogin");
        }

        return result;
    }

    @Override
    public String signUamauthClient(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody reqBodyRedir = new FormBody.Builder()
                .add("_json_att", "")
                .build();
        RequestBody reqBodyUamauth = new FormBody.Builder()
                .add("tk", reqData.getString("tk"))
                .build();

        Request reqRedir = new Request.Builder()
                .url(urlMap.get("singUserLogin"))
                .post(reqBodyRedir)
                .build();

        Request reqUamauth = new Request.Builder()
                .url(urlMap.get("signUamauth"))
                .post(reqBodyUamauth).build();

        try {
            if (!okHttpClient.newCall(reqRedir).execute().isSuccessful()) {
                throw new IOException("Redir exception");
            }

            Response response = okHttpClient.newCall(reqUamauth).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"result_code\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signUamauthClient");
        }

        return result;
    }

    @Override
    public String queryPassenger(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att", reqData.getString("_json_att"))
                .add("REPEAT_SUBMIT_TOKEN", reqData.getString("REPEAT_SUBMIT_TOKEN"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("queryPassenger"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signLogin");
        }

        return result;
    }

    @Override
    public String queryNoComplete(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att", reqData.getString("_json_att"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("queryNoComplete"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("signLogin");
        }

        return result;
    }

    @Override
    public String queryTicket(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        String urlGetQuery = urlMap.get("queryTicket")
                + "?leftTicketDTO.train_date="   + reqData.getString("train_date")
                + "&leftTicketDTO.from_station=" + reqData.getString("fromStation")
                + "&leftTicketDTO.to_station="   + reqData.getString("toStation")
                + "&purpose_codes=ADULT";

        HttpURLConnection connection = null;

        Request request = new Request.Builder()
                .url(urlGetQuery)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();
            JSONObject resultJson = JSONObject.parseObject(result);

            if (resultJson.containsKey("httpstatus") && resultJson.getInteger("httpstatus") == 400) {
                // 尝试获取查询url后再次查询(未知响应)
                Request requestInit = new Request.Builder()
                        .url(urlMap.get("quertTicketInit"))
                        .build();

                Response responseInit = okHttpClient.newCall(requestInit).execute();

                if (responseInit.isSuccessful()) {
                    String contentTypeInit = responseInit.header("Content-Type");
                    ResponseBody resBodyInit = responseInit.body();

                    if (contentTypeInit != null && resBodyInit != null
                            && contentTypeInit.startsWith("text/html;charset=utf-8")) {
                        Map<String, String> varMap = TicketUtil.getHtmlVarMap(resBodyInit.string());
                        String newUrl = urlMap.get("12306Host") + "/otn/" + varMap.get("CLeftTicketUrl");
                        urlMap.put("queryTicket", newUrl);

                        resBodyInit.close();
                        result = queryTicket(reqData, okHttpClient);
                    }
                }

                responseInit.close();

            } else if (resultJson.containsKey("c_url")){
                // 尝试获取查询url后再次查询(url响应)
                String newUrl = urlMap.get("12306Host") + "/otn/" + resultJson.getString("c_url");
                urlMap.put("queryTicket", newUrl);

                result = queryTicket(reqData, okHttpClient);
            }
        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("queryTicket");
        }

        return result;
    }

    @Override
    public String orderCheckUser(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att", reqData.getString("_json_att"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderCheckUser"))
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderCheckUser");
        }

        return result;
    }

    @Override
    public String orderSubmit(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("back_train_date",         reqData.getString("back_train_date"))
                .add("purpose_codes",           reqData.getString("purpose_codes"))
                .add("query_from_station_name", reqData.getString("query_from_station_name"))
                .add("query_to_station_name",   reqData.getString("query_to_station_name"))
                .add("secretStr",               reqData.getString("secretStr"))
                .add("tour_flag",               reqData.getString("tour_flag"))
                .add("train_date",              reqData.getString("train_date"))
                .add("undefined",               reqData.getString("undefined"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderSubmit"))
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderSubmit");
        }

        return result;
    }

    @Override
    public String orderInitDc(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att", reqData.getString("_json_att"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderIndex"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("text/html")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderInitDc");
        }

        return result;
    }

    @Override
    public String orderCheckInfo(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att",           reqData.getString("_json_att"))
                .add("bed_level_order_num", reqData.getString("bed_level_order_num"))
                .add("cancel_flag",         reqData.getString("cancel_flag"))
                .add("oldPassengerStr",     reqData.getString("oldPassengerStr"))
                .add("passengerTicketStr",  reqData.getString("passengerTicketStr"))
                .add("randCode",            reqData.getString("randCode"))
                .add("REPEAT_SUBMIT_TOKEN", reqData.getString("globalRepeatSubmitToken"))
                .add("tour_flag",           reqData.getString("member_tourFlag"))
                .add("whatsSelect",         reqData.getString("id_type_code"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderCheckInfo"))
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderCheckInfo");
        }

        return result;
    }

    @Override
    public String orderQueueCount(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att",           reqData.getString("_json_att"))
                .add("fromStationTelecode", reqData.getString("fromStationTelecode"))
                .add("leftTicket",          reqData.getString("leftTicketStr"))
                .add("purpose_codes",       reqData.getString("purpose_codes"))
                .add("REPEAT_SUBMIT_TOKEN", reqData.getString("globalRepeatSubmitToken"))
                .add("seatType",            reqData.getString("seatType"))
                .add("stationTrainCode",    reqData.getString("stationTrainCode"))
                .add("toStationTelecode",   reqData.getString("toStationTelecode"))
                .add("train_date",          reqData.getString("train_date_gmt"))
                .add("train_location",      reqData.getString("train_location"))
                .add("train_no",            reqData.getString("train_no"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderQueue"))
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderQueueCount");
        }

        return result;
    }

    @Override
    public String orderConfirmSingle(JSONObject reqData, OkHttpClient okHttpClient) {
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att",           reqData.getString("_json_att"))
                .add("choose_seats",        reqData.getString("choose_seats"))
                .add("dwAll",               reqData.getString("isDw"))
                .add("key_check_isChange",  reqData.getString("key_check_isChange"))
                .add("leftTicketStr",       reqData.getString("leftTicketStr"))
                .add("oldPassengerStr",     reqData.getString("oldPassengerStr"))
                .add("passengerTicketStr",  reqData.getString("passengerTicketStr"))
                .add("purpose_codes",       reqData.getString("purpose_codes"))
                .add("randCode",            reqData.getString("randCode"))
                .add("REPEAT_SUBMIT_TOKEN", reqData.getString("globalRepeatSubmitToken"))
                .add("roomType",            reqData.getString("roomType"))
                .add("seatDetailType",      reqData.getString("seatDetailType"))
                .add("train_location",      reqData.getString("train_location"))
                .add("whatsSelect",         reqData.getString("id_type_code"))
                .build();

        Request request = new Request.Builder()
                .url(urlMap.get("orderConfirm"))
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderQueueCount");
        }

        return result;
    }

    @Override
    public String orderWaitTime(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        String urlGetString = urlMap.get("orderWaitTime")
                + "?random="              + reqData.getString("random")
                + "&tourFlag="            + reqData.getString("tourFlag")
                + "&_json_att="           + reqData.getString("_json_att")
                + "&REPEAT_SUBMIT_TOKEN=" + reqData.getString("globalRepeatSubmitToken");

        Request request = new Request.Builder()
                .url(urlGetString)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderWaitTime");
        }

        return result;
    }

    @Override
    public String orderDcQueue(JSONObject reqData, OkHttpClient okHttpClient) {
        String result = null;

        RequestBody requestBody = new FormBody.Builder()
                .add("_json_att",           reqData.getString("_json_att"))
                .add("orderSequence_no",    reqData.getString("orderSequence_no"))
                .add("REPEAT_SUBMIT_TOKEN", reqData.getString("globalRepeatSubmitToken"))
                .build();

        Request request = new Request.Builder().url(urlMap.get("orderConfirm")).post(requestBody).build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            if (response.isSuccessful()) {
                String contentType = response.header("Content-Type");
                ResponseBody resBody = response.body();

                if (contentType != null && resBody != null) {
                    if (contentType.startsWith("application/json")) {
                        result = resBody.string();
                    } else {
                        result = "{\"httpstatus\":400}";
                    }

                    resBody.close();
                }
            }
            response.close();

        } catch (Exception exc) {
            LogUtil.log4j2().warn(exc.getMessage());
            LogUtil.log4j2().warn("orderDcQueue");
        }

        return result;
    }

    @Override
    public String creatOrderList(JSONObject reqData, OkHttpClient okHttpClient) {
        return null;
    }

    @Override
    public String queryOrderList(JSONObject reqData, OkHttpClient okHttpClient) {
        return null;
    }

    @Override
    public void testOrder(OkHttpClient okHttpClient) {
        TicketTask ticketTask = new TicketTask();

        ticketTask.setStatus("Work");

        ticketTask.setFromStation("YLZ");
        ticketTask.setToStation("NNZ");
        ticketTask.setTrainDate("2018-04-22");
        ticketTask.setTrainNumber("D8386");
        ticketTask.setFromStationName("玉林");
        ticketTask.setToStationName("南宁");

        ticketTask.setTicketType("O");
        ticketTask.setPassengerName("陶祖芹");
        ticketTask.setPassengerType("1");
        ticketTask.setPassengerId("452501199107270511");
        ticketTask.setPassengerIdType("1");
        ticketTask.setCellPhone("18007758403");

        ticketTask.setUserId(CheckUtil.calcMd5("taozuqin@163.com"));


        Map<String, TrainNumber> trainNumberMap = new HashMap<>();
        JSONObject reqData = new JSONObject();
        JSONObject resData = new JSONObject();

        reqData.put("train_date",  ticketTask.getTrainDate());
        reqData.put("fromStation", ticketTask.getFromStation());
        reqData.put("toStation",   ticketTask.getToStation());
        reqData.put("query_from_station_name", ticketTask.getFromStationName());
        reqData.put("query_to_station_name",   ticketTask.getToStationName());
        reqData.put("oldPassengerStr",    TicketUtil.getOldPassengerStr(ticketTask));

        while (true) {
            resData = JSON.parseObject(queryTicket(reqData, okHttpClient));
            if (resData.getInteger("httpstatus") == 200) {
                JSONArray trainNumberData = resData.getJSONObject("data").getJSONArray("result");

                for (String item : trainNumberData.toJavaList(String.class)) {
                    TrainNumber trainNumber = TicketFactroy.createTrainNumber(item);
                    trainNumberMap.put(trainNumber.getTrainNumber(), trainNumber);
                }
            }

            TrainNumber trainNumber = trainNumberMap.get(ticketTask.getTrainNumber());

            if (trainNumber.getCanOrder().equals("Y")) {
                String secretStr = CheckUtil.urlDecode(trainNumber.getSecretStr(), "UTF-8");

                reqData.put("secretStr", secretStr);
                reqData.put("stationTrainCode", trainNumber.getTrainNumber());
                reqData.put("train_no", trainNumber.getTrainCdoe());
                reqData.put("fromStationTelecode", trainNumber.getFromStation());
                reqData.put("toStationTelecode", trainNumber.getToStation());
                reqData.put("train_location", trainNumber.getTrainLocation());
                break;
            }
        }

        autoStep(reqData, ticketTask, okHttpClient);
    }

    /*------------------------------------------------------------------------------------------*/
    /* 下单执行步骤
    /*------------------------------------------------------------------------------------------*/
    private void autoStep(JSONObject reqData, TicketTask ticketTask, OkHttpClient okHttpClient) {
        JSONObject resData = null;

        reqData.put("_json_att", "");
        reqData.put("randCode",  "");
        reqData.put("undefined", "");
        reqData.put("choose_seats", "");
        reqData.put("tour_flag", "dc");
        reqData.put("cancel_flag", "2");
        reqData.put("purpose_codes", "ADULT");
        reqData.put("roomType", "00");
        reqData.put("seatDetailType", "000");
        reqData.put("bed_level_order_num", "000000000000000000000000000000");

        reqData.put("train_date",  ticketTask.getTrainDate());
        reqData.put("fromStation", ticketTask.getFromStation());
        reqData.put("toStation",   ticketTask.getToStation());
        reqData.put("query_from_station_name", ticketTask.getFromStationName());
        reqData.put("query_to_station_name",   ticketTask.getToStationName());

        // 校验用户
        LogUtil.log4j2().info("CheckUser");
        resData = JSON.parseObject(orderCheckUser(reqData, okHttpClient));
        if (resData.getInteger("httpstatus") == 200) {
            if (!resData.getJSONObject("data").getBoolean("flag")) {
                LogUtil.log4j2().warn("Not pass CheckUser");
                return;
            }
        }

        // 选定车次
        LogUtil.log4j2().info("Submit");
        reqData.put("back_train_date", LogUtil.getToday());
        resData = JSON.parseObject(orderSubmit(reqData, okHttpClient));
        if (resData.getInteger("httpstatus") == 200) {
            if (!resData.getBoolean("status")) {
                LogUtil.log4j2().warn("Not pass Submit");
                return;
            }
        }

        // 初始化订单
        LogUtil.log4j2().info("InitDc");
        String initDcHtml = orderInitDc(reqData, okHttpClient);
        Map<String, String> varMap = TicketUtil.getHtmlVarMap(initDcHtml);

        if (varMap.size() > 13) {
            if (varMap.containsKey("ticketInfoForPassengerForm")) {
                String infoData = varMap.get("ticketInfoForPassengerForm");
                varMap.put("key_check_isChange", TicketUtil.getStringJson("key_check_isChange", infoData));
                varMap.put("leftTicketStr", TicketUtil.getStringJson("leftTicketStr", infoData));
                varMap.put("purpose_codes", TicketUtil.getStringJson("purpose_codes", infoData));
            }
            reqData.putAll(varMap);
        } else {
            LogUtil.log4j2().warn("Not pass InitDc");
            return;
        }

        if (varMap.containsKey("init_seatTypes")) {
            String seatTypes = varMap.get("init_seatTypes");
            StringBuffer canSeatTypes = new StringBuffer();
            JSONArray seatJsons = JSONArray.parseArray(seatTypes);

            for (int i = 0; i < seatJsons.size(); ++i) {
                JSONObject seatJson = seatJsons.getJSONObject(i);
                canSeatTypes.append(seatJson.getString("id"));
            }

            for (byte seat : ticketTask.getTicketType().getBytes()) {
                if (canSeatTypes.toString().indexOf(seat) != -1) {
                    reqData.put("seatType", new String(new byte[]{seat}));
                    break;
                }
            }

            if (reqData.containsKey("seatType")) {
                reqData.put("train_date_gmt", TicketUtil.getDateGMT(reqData.getString("train_date")));
            } else {
                return;
            }
        } else {
            LogUtil.log4j2().warn("Can not get seat type");
            return;
        }

        // 提交订单
        LogUtil.log4j2().info("CheckInfo");
        reqData.put("oldPassengerStr",    TicketUtil.getOldPassengerStr(ticketTask));
        reqData.put("passengerTicketStr", TicketUtil.getPassengerTicketStr(ticketTask, reqData.getString("seatType")));

        resData = JSON.parseObject(orderCheckInfo(reqData, okHttpClient));

        if (resData.getInteger("httpstatus") == 200) {
            if (!resData.getJSONObject("data").getBoolean("submitStatus")) {
                LogUtil.log4j2().warn("Not pass CheckInfo");
                return;
            }
        }

        // 选座
        int ticketSum = 0;
        LogUtil.log4j2().info("QueueCount");
        resData = JSON.parseObject(orderQueueCount(reqData, okHttpClient));
        if (resData.getInteger("httpstatus") == 200) {
            if (resData.getBoolean("status")) {
                String[] ticketData = resData.getJSONObject("data").getString("ticket").split(",");
                ticketSum = Integer.valueOf(ticketData[0]);

                if (ticketSum == 0) {
                    if (!ticketTask.getTicketType().contains("0")) {
                        LogUtil.log4j2().warn("Not pass QueueCount");
                        return;
                    }
                }
            } else {
                return;
            }
        }

        // 确认订单
        LogUtil.log4j2().info("ConfirmSingle");
        resData = JSON.parseObject(orderConfirmSingle(reqData, okHttpClient));
        if (resData.getInteger("httpstatus") == 200) {
            if (!resData.getJSONObject("data").getBoolean("submitStatus")) {
                LogUtil.log4j2().warn("Not pass ConfirmSingle");
                return;
            }
        }

        // 订单
//        String orderId = null;
//        LogUtil.log4j2().info("WaitTime");
//
//        while (orderId == null) {
//            reqData.put("random", String.valueOf(System.currentTimeMillis()));
//            resData = JSON.parseObject(orderWaitTime(reqData, okHttpClient));
//
//            if (resData.getInteger("httpstatus") == 200) {
//                JSONObject resList = resData.getJSONObject("data");
//
//                if (resList.getInnerMap().containsKey("msg")) {
//                    ticketTask.setStatus("Work");
//                    return;
//                }
//
//                orderId = resList.getString("orderId");
//
//                try {
//                    Thread.sleep(3 * 1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }

        LogUtil.log4j2().info("Oder Confirm!");
        ticketTask.setStatus("Confirm");
//        ticketTask.setOrderId(orderId);
        ticketTaskMapper.update(ticketTask);
    }

}
